#!/bin/bash

# =============================================
# SSH远程Git操作脚本
# 功能：通过SSH连接到服务器执行git fetch和git pull
# 作者：AI助手
# 版本：1.0
# =============================================

# 设置脚本选项
set -e  # 遇到错误立即退出
set -u  # 使用未定义变量时报错

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 显示帮助信息
show_help() {
    cat << EOF
用法: $0 [选项]

选项:
    -h, --help          显示此帮助信息
    -s, --server        服务器地址（格式：user@hostname）
    -p, --port          SSH端口（默认：22）
    -d, --directory     远程目录路径
    -i, --identity      SSH私钥文件路径
    -b, --branch        要拉取的分支（默认：当前分支）
    -f, --force         强制拉取（使用git pull --force）
    --git-dir           Git目录路径（如果不同于工作目录）
    --remote            远程仓库名称（默认：origin）
    --no-fetch          跳过git fetch，直接执行git pull
    --dry-run           试运行，显示将要执行的命令但不实际执行

示例:
    $0 -s user@example.com -d /var/www/myapp
    $0 -s deploy@192.168.1.100 -p 2222 -d /app -i ~/.ssh/deploy_key
    $0 -s user@server.com -d /project --branch main --dry-run

环境变量:
    可以通过环境变量设置默认值：
    DEPLOY_SERVER, DEPLOY_PORT, DEPLOY_DIR, DEPLOY_KEY
EOF
}

# 默认值
SSH_USER="eduserver"
SERVER="124.71.10.84"
SSH_PORT=22
GIT_BRANCH=""
GIT_REMOTE="origin"
SKIP_FETCH=false
FORCE_PULL=false
DRY_RUN=false
GIT_DIR=""
REMOTE_DIR='/home/eduserver/Sites/eduPrimary/primaryEdu'

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -s|--server)
            SERVER="$2"
            shift 2
            ;;
        -p|--port)
            SSH_PORT="$2"
            shift 2
            ;;
        -d|--directory)
            REMOTE_DIR="$2"
            shift 2
            ;;
        -i|--identity)
            SSH_KEY="$2"
            shift 2
            ;;
        -b|--branch)
            GIT_BRANCH="$2"
            shift 2
            ;;
        -f|--force)
            FORCE_PULL=true
            shift
            ;;
        --git-dir)
            GIT_DIR="$2"
            shift 2
            ;;
        --remote)
            GIT_REMOTE="$2"
            shift 2
            ;;
        --no-fetch)
            SKIP_FETCH=true
            shift
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        *)
            log_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
done

# 检查必需参数
check_requirements() {
    local missing_params=()
    
    # 检查服务器地址
    if [[ -z "${SERVER:-}" ]] && [[ -z "${DEPLOY_SERVER:-}" ]]; then
        missing_params+=("服务器地址")
    else
        SERVER="${SERVER:-$DEPLOY_SERVER}"
    fi
    
    # 检查目录
    if [[ -z "${REMOTE_DIR:-}" ]] && [[ -z "${DEPLOY_DIR:-}" ]]; then
        missing_params+=("远程目录")
    else
        REMOTE_DIR="${REMOTE_DIR:-$DEPLOY_DIR}"
    fi
    
    # 设置其他默认值
    SSH_PORT="${SSH_PORT:-${DEPLOY_PORT:-22}}"
    if [[ -n "${DEPLOY_KEY:-}" ]]; then
        SSH_KEY="${SSH_KEY:-$DEPLOY_KEY}"
    fi
    
    if [[ ${#missing_params[@]} -gt 0 ]]; then
        log_error "缺少必需参数: ${missing_params[*]}"
        echo
        show_help
        exit 1
    fi
}

# 验证SSH连接
test_ssh_connection() {
    log_info "测试SSH连接到服务器: $SERVER"
    
    local ssh_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        ssh_cmd="$ssh_cmd -i $SSH_KEY"
    fi
    ssh_cmd="$ssh_cmd $SSH_USER@$SERVER 'echo \"SSH连接测试成功\"'"
    
    if $DRY_RUN; then
        log_info "试运行SSH命令: $ssh_cmd"
        return 0
    fi
    
    if eval "$ssh_cmd" > /dev/null 2>&1; then
        log_success "SSH连接测试成功"
        return 0
    else
        log_error "SSH连接失败"
        return 1
    fi
}

# 验证远程目录
check_remote_directory() {
    log_info "检查远程目录: $REMOTE_DIR"
    
    local check_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        check_cmd="$check_cmd -i $SSH_KEY"
    fi
    check_cmd="$check_cmd $SERVER \"test -d \\\"$REMOTE_DIR\\\" && echo '目录存在' || echo '目录不存在'\""
    
    if $DRY_RUN; then
        log_info "试运行目录检查: $check_cmd"
        return 0
    fi
    
    local result
    result=$(eval "$check_cmd" 2>/dev/null || true)
    
    if [[ "$result" == "目录存在" ]]; then
        log_success "远程目录存在"
        return 0
    else
        log_error "远程目录不存在或不可访问: $REMOTE_DIR"
        return 1
    fi
}

# 检查Git仓库
check_git_repository() {
    log_info "检查Git仓库状态"
    
    local git_cmd="cd \\\"$REMOTE_DIR\\\""
    if [[ -n "$GIT_DIR" ]]; then
        git_cmd="cd \\\"$GIT_DIR\\\""
    fi
    git_cmd="$git_cmd && git status --porcelain > /dev/null 2>&1 && echo 'Git仓库正常' || echo 'Git仓库异常'"
    
    local full_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        full_cmd="$full_cmd -i $SSH_KEY"
    fi
    full_cmd="$full_cmd $SERVER \"$git_cmd\""
    
    if $DRY_RUN; then
        log_info "试运行Git检查: $full_cmd"
        return 0
    fi
    
    local result
    result=$(eval "$full_cmd" 2>/dev/null || true)
    
    if [[ "$result" == "Git仓库正常" ]]; then
        log_success "Git仓库状态正常"
        return 0
    else
        log_error "Git仓库状态异常或不是Git仓库"
        return 1
    fi
}

# 执行Git Fetch
git_fetch() {
    log_info "执行 git fetch..."
    
    local git_cmd="cd \\\"$REMOTE_DIR\\\""
    if [[ -n "$GIT_DIR" ]]; then
        git_cmd="cd \\\"$GIT_DIR\\\""
    fi
    git_cmd="$git_cmd && git fetch $GIT_REMOTE"
    
    local full_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        full_cmd="$full_cmd -i $SSH_KEY"
    fi
    full_cmd="$full_cmd $SERVER \"$git_cmd\""
    
    if $DRY_RUN; then
        log_info "试运行Git Fetch: $full_cmd"
        return 0
    fi
    
    if eval "$full_cmd" 2>&1 | while read line; do log_info "$line"; done; then
        log_success "Git fetch 完成"
        return 0
    else
        log_error "Git fetch 失败"
        return 1
    fi
}

# 执行Git Pull
git_pull() {
    log_info "执行 git pull..."
    
    local pull_cmd="git pull"
    if $FORCE_PULL; then
        pull_cmd="git pull --force"
    fi
    
    if [[ -n "$GIT_BRANCH" ]]; then
        pull_cmd="$pull_cmd $GIT_REMOTE $GIT_BRANCH"
    fi
    
    local git_cmd="cd \\\"$REMOTE_DIR\\\""
    if [[ -n "$GIT_DIR" ]]; then
        git_cmd="cd \\\"$GIT_DIR\\\""
    fi
    git_cmd="$git_cmd && $pull_cmd"
    
    local full_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        full_cmd="$full_cmd -i $SSH_KEY"
    fi
    full_cmd="$full_cmd $SERVER \"$git_cmd\""
    
    if $DRY_RUN; then
        log_info "试运行Git Pull: $full_cmd"
        return 0
    fi
    
    log_info "开始拉取代码..."
    if eval "$full_cmd" 2>&1 | while read line; do
        if echo "$line" | grep -q "Already up to date"; then
            log_success "$line"
        elif echo "$line" | grep -q "error:\|fatal:"; then
            log_error "$line"
        else
            log_info "$line"
        fi
    done; then
        log_success "Git pull 完成"
        return 0
    else
        log_error "Git pull 失败"
        return 1
    fi
}

# 显示Git状态
show_git_status() {
    log_info "显示Git仓库状态"
    
    local git_cmd="cd \\\"$REMOTE_DIR\\\""
    if [[ -n "$GIT_DIR" ]]; then
        git_cmd="cd \\\"$GIT_DIR\\\""
    fi
    git_cmd="$git_cmd && echo '=== 当前分支 ===' && git branch --show-current && echo '=== 最近提交 ===' && git log --oneline -5 && echo '=== 状态 ===' && git status --short"
    
    local full_cmd="ssh -p $SSH_PORT"
    if [[ -n "${SSH_KEY:-}" ]]; then
        full_cmd="$full_cmd -i $SSH_KEY"
    fi
    full_cmd="$full_cmd $SERVER \"$git_cmd\""
    
    if $DRY_RUN; then
        log_info "试运行状态检查: $full_cmd"
        return 0
    fi
    
    log_info "Git仓库状态:"
    eval "$full_cmd" 2>&1 | while read line; do
        if echo "$line" | grep -q "==="; then
            log_info "$line"
        else
            echo "    $line"
        fi
    done
}

# 主函数
main() {
    log_info "开始远程Git操作脚本"
    log_info "服务器: $SERVER, 目录: $REMOTE_DIR, 端口: $SSH_PORT"
    
    # 检查参数
    check_requirements
    
    # 测试连接
    if ! test_ssh_connection; then
        exit 1
    fi
    
    # 检查目录
    if ! check_remote_directory; then
        exit 1
    fi
    
    # 检查Git仓库
    if ! check_git_repository; then
        exit 1
    fi
    
    # 显示当前状态
    show_git_status
    
    # 执行Git Fetch（除非跳过）
    if ! $SKIP_FETCH; then
        if ! git_fetch; then
            log_error "操作中止"
            exit 1
        fi
    else
        log_info "跳过 git fetch"
    fi
    
    # 执行Git Pull
    if ! git_pull; then
        log_error "操作中止"
        exit 1
    fi
    
    # 显示最终状态
    show_git_status
    
    log_success "远程Git操作完成"
}

# 信号处理
trap 'log_error "脚本被用户中断"; exit 1' INT TERM

# 执行主函数
main "$@"
